package com.efun.framework.dao;

import com.alibaba.druid.pool.DruidDataSource;
import org.beetl.sql.core.ClasspathLoader;
import org.beetl.sql.core.Interceptor;
import org.beetl.sql.core.NameConversion;
import org.beetl.sql.core.UnderlinedNameConversion;
import org.beetl.sql.core.db.DBStyle;
import org.beetl.sql.core.db.MySqlStyle;
import org.beetl.sql.ext.DebugInterceptor;
import org.beetl.sql.ext.spring4.BeetlSqlDataSource;
import org.beetl.sql.ext.spring4.BeetlSqlScannerConfigurer;
import org.beetl.sql.ext.spring4.SqlManagerFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * beetl自动化配置
 * @author kinven on 17/7/9.
 */
@Configuration
@EnableConfigurationProperties({BeetlsqlProperties.class})
public class BeetlsqlAutoConfiguration {
    private BeetlsqlProperties beetlsqlProperties;

    public BeetlsqlAutoConfiguration(BeetlsqlProperties beetlsqlProperties){
        this.beetlsqlProperties = beetlsqlProperties;
    }

    @Bean(name = "beetlSqlScannerConfigurer")
    public BeetlSqlScannerConfigurer getBeetlSqlScannerConfigurer() {
        BeetlSqlScannerConfigurer conf = new BeetlSqlScannerConfigurer();
        conf.setBasePackage(beetlsqlProperties.getBasePackage());
        conf.setDaoSuffix(beetlsqlProperties.getDaoSuffix());
        conf.setSqlManagerFactoryBeanName("sqlManagerFactoryBean");
        return conf;
    }

    /**
     * 默认使用Debug拦截器打印SQL。
     * @param beetlSqlDataSource
     * @param nameConversion
     * @param classpathLoader
     * @param dbStyle
     * @return
     */
    @Bean(name = "sqlManagerFactoryBean")
    @Primary
    public SqlManagerFactoryBean getSqlManagerFactoryBean(
            BeetlSqlDataSource beetlSqlDataSource,
            NameConversion nameConversion,
            ClasspathLoader classpathLoader,
            DBStyle dbStyle) {
        SqlManagerFactoryBean factory = new SqlManagerFactoryBean();
        factory.setCs(beetlSqlDataSource);
        factory.setDbStyle(dbStyle);
        factory.setInterceptors(new Interceptor[]{new DebugInterceptor()});
        factory.setNc(nameConversion);
        factory.setSqlLoader(classpathLoader);
        return factory;
    }

    @Bean
    public BeetlSqlDataSource beetlSqlDataSource(@Qualifier("writeDruidDataSource") DataSource writeDatasource,@Qualifier("readDruidDataSource") DataSource readDatasource){
        BeetlSqlDataSource source = new BeetlSqlDataSource();
        source.setMasterSource(writeDatasource);
        source.setSlaves(new DataSource[]{readDatasource});
        return source;
    }

    @Bean
    public NameConversion underlinedNameConversion(){
        return new UnderlinedNameConversion();
    }

    @Bean
    public ClasspathLoader classpathLoader(){
        return new ClasspathLoader(beetlsqlProperties.getSqlLoaderPath());
    }

    /**
     * 默认使用Mysql数据类型，
     * 如果接入其他数据库，请自行修改
     * @return
     */
    @Bean
    public DBStyle dbStyle() {
        DBStyle dbStyle = new MySqlStyle();
        if(beetlsqlProperties.getDbStyle().equalsIgnoreCase("mysql")){
            return new MySqlStyle();
        }
        return dbStyle;
    }

    @Bean(name="txManager")
    public DataSourceTransactionManager getDataSourceTransactionManager(@Qualifier("writeDruidDataSource") DataSource datasource) {
        DataSourceTransactionManager dsm = new DataSourceTransactionManager();
        dsm.setDataSource(datasource);
        return dsm;
    }

    /**
     * DataSource 从数据源配置
     * @return
     */
    @ConfigurationProperties(prefix = "spring.datasource.druid.read")
    @Bean(name = "readDruidDataSource")
    public DataSource readDruidDataSource() {
        return new DruidDataSource();
    }
    /**
     * DataSource 主数据源配置
     * @return
     */
    @ConfigurationProperties(prefix = "spring.datasource.druid.write")
    @Bean(name = "writeDruidDataSource")
    @Primary
    public DataSource writeDruidDataSource() {
        return new DruidDataSource();
    }

}
